<template>
  <div class="protocol-management">
    <div class="header">
      <h2>协议管理</h2>
      <el-button type="primary" @click="openAddDialog">+ 新增协议</el-button>
    </div>
    <el-row :gutter="20" class="protocol-list" justify="start">
      <el-col v-for="item in protocols" :key="item.id" :span="8" class="protocol-col">
        <el-card shadow="hover" class="protocol-card">
          <div class="card-header">
            <img :src="getProtocolIcon(item.type)" class="protocol-icon" @error="onImgError($event)" />
            <div class="protocol-info">
              <div class="protocol-title">名称：{{ item.name }}</div>
              <div>服务类型：{{ item.type }}</div>
              <div>端口号：{{ item.port }}</div>
              <div>开启TLS：{{ item.tls ? '已开启' : '未开启' }}</div>
              <div>创建时间：{{ item.createTime }}</div>
            </div>
          </div>
          <div class="card-footer">
            <span class="footer-name">{{ item.name }}</span>
            <el-switch v-model="item.enabled" active-text="已开启" inactive-text="已关闭" @change="toggleEnable(item)" />
            <el-button icon="el-icon-star-off" circle @click="setFavorite(item)" :type="item.favorite ? 'warning' : 'default'" size="mini" />
            <el-button icon="el-icon-edit" circle @click="openEditDialog(item)" size="mini" />
            <el-button icon="el-icon-delete" circle @click="deleteProtocol(item)" size="mini" />
            <el-button type="primary" size="mini" @click="openTestDialog(item)">设备适配测试</el-button>
            <el-button size="mini" @click="openDiscoveryDialog(item)">设备发现</el-button>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 新增/编辑协议弹窗 -->
    <el-dialog :title="dialogTitle" :visible.sync="showDialog" width="500px" @close="resetDialog">
      <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
        <el-form-item label="协议类型" prop="type">
          <el-select v-model="form.type" placeholder="请选择协议类型" :disabled="!!form.id">
            <el-option v-for="item in protocolTypes" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="协议名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入协议名称" />
        </el-form-item>
        <el-form-item label="设备地址" prop="address">
          <el-input v-model="form.address" placeholder="请输入设备地址" />
        </el-form-item>
        <el-form-item label="端口号" prop="port">
          <el-input-number v-model="form.port" :min="1" :max="65535" />
        </el-form-item>
        <el-form-item label="通信超时(ms)" prop="timeout">
          <el-input-number v-model="form.timeout" :min="100" :max="60000" />
        </el-form-item>
        <el-form-item label="自动重连">
          <el-checkbox v-model="form.autoReconnect">自动重连</el-checkbox>
        </el-form-item>
        <el-form-item label="数据加密">
          <el-checkbox v-model="form.encryption">数据加密</el-checkbox>
        </el-form-item>
        <el-form-item label="开启TLS">
          <el-switch v-model="form.tls" />
        </el-form-item>
      </el-form>
      <div style="text-align:right;">
        <el-button @click="showDialog = false">取消</el-button>
        <el-button type="primary" @click="submitForm">保存配置</el-button>
      </div>
    </el-dialog>

    <!-- 设备适配测试弹窗 -->
    <el-dialog title="设备适配测试" :visible.sync="showTestDialog" width="400px" @close="resetTestDialog">
      <el-form label-width="100px">
        <el-form-item label="设备类型">
          <el-select v-model="testDeviceType" placeholder="请选择设备类型">
            <el-option v-for="item in deviceTypes" :key="item" :label="item" :value="item" />
          </el-select>
        </el-form-item>
      </el-form>
      <div v-if="testResult">
        <el-alert :title="testResult.status" :type="testResult.success ? 'success' : 'error'" show-icon />
        <div style="margin-top:10px;">适配率：{{ testResult.rate }}%</div>
        <div>报告：{{ testResult.report }}</div>
      </div>
      <div slot="footer">
        <el-button @click="showTestDialog = false">关闭</el-button>
        <el-button type="primary" @click="runTest" :disabled="!testDeviceType">开始测试</el-button>
      </div>
    </el-dialog>

    <!-- 设备发现弹窗 -->
    <el-dialog title="设备发现/手动添加" :visible.sync="showDiscoveryDialog" width="500px" @close="resetDiscoveryDialog">
      <el-tabs v-model="discoveryTab">
        <el-tab-pane label="设备发现" name="scan">
          <el-button type="primary" @click="scanDevices">扫描局域网设备</el-button>
          <el-table :data="scannedDevices" style="margin-top:10px;">
            <el-table-column prop="id" label="设备ID" width="120" />
            <el-table-column prop="name" label="设备名称" />
            <el-table-column prop="status" label="状态" />
            <el-table-column label="操作" width="100">
              <template slot-scope="scope">
                <el-button type="text" size="mini" @click="associateDevice(scope.row)">关联物模型</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        <el-tab-pane label="手动添加" name="manual">
          <el-form :model="manualDevice" label-width="100px">
            <el-form-item label="设备ID">
              <el-input v-model="manualDevice.id" />
            </el-form-item>
            <el-form-item label="设备名称">
              <el-input v-model="manualDevice.name" />
            </el-form-item>
            <el-form-item label="通讯参数">
              <el-input v-model="manualDevice.param" />
            </el-form-item>
            <el-form-item label="物模型">
              <el-select v-model="manualDevice.model" placeholder="请选择物模型">
                <el-option v-for="item in deviceModels" :key="item" :label="item" :value="item" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="addManualDevice">添加设备</el-button>
            </el-form-item>
          </el-form>
        </el-tab-pane>
      </el-tabs>
    </el-dialog>
  </div>
</template>

<script>
// 协议类型图标可用本地图片或网络图片，这里用网络图片做示例
const protocolIcons = {
  MQTT: 'https://img.icons8.com/color/96/000000/mqtt.png',
  ModbusRTU: 'https://img.icons8.com/color/96/000000/serial-tasks.png',
  ModbusTCP: 'https://img.icons8.com/color/96/000000/network-cable.png',
  OPCUA: 'https://img.icons8.com/color/96/000000/connection-status-on.png',
  Profinet: 'https://img.icons8.com/color/96/000000/ethernet-on.png',
  TCP_SERVER: 'https://img.icons8.com/color/96/000000/lan.png',
  HTTP_SERVER: 'https://img.icons8.com/color/96/000000/http.png',
  WEBSOCKET_SERVER: 'https://img.icons8.com/color/96/000000/websocket.png',
}

export default {
  name: 'ProtocolManagement',
  data() {
    return {
      // 协议类型
      protocolTypes: [
        { label: 'MQTT', value: 'MQTT' },
        { label: 'ModbusRTU', value: 'ModbusRTU' },
        { label: 'ModbusTCP', value: 'ModbusTCP' },
        { label: 'OPCUA', value: 'OPCUA' },
        { label: 'Profinet', value: 'Profinet' },
        { label: 'TCP服务器', value: 'TCP_SERVER' },
        { label: 'HTTP服务器', value: 'HTTP_SERVER' },
        { label: 'WebSocket服务器', value: 'WEBSOCKET_SERVER' },
      ],
      // 协议卡片数据（mock）
      protocols: [], // 初始化为空，加载时从localStorage获取
      // 新增/编辑弹窗
      showDialog: false,
      dialogTitle: '新增协议',
      form: {
        id: null,
        type: '',
        name: '',
        address: '',
        port: 1883,
        timeout: 3000,
        autoReconnect: false,
        encryption: false,
        tls: false,
      },
      rules: {
        type: [{ required: true, message: '请选择协议类型', trigger: 'change' }],
        name: [{ required: true, message: '请输入协议名称', trigger: 'blur' }],
        address: [{ required: true, message: '请输入设备地址', trigger: 'blur' }],
        port: [{ required: true, message: '请输入端口号', trigger: 'blur' }],
        timeout: [{ required: true, message: '请输入通信超时时间', trigger: 'blur' }],
      },
      // 设备适配测试
      showTestDialog: false,
      testDeviceType: '',
      deviceTypes: ['机床', '空压机', '机器人', 'PLC', '传感器'],
      testResult: null,
      // 设备发现/手动添加
      showDiscoveryDialog: false,
      discoveryTab: 'scan',
      scannedDevices: [],
      manualDevice: {
        id: '',
        name: '',
        param: '',
        model: '',
      },
      deviceModels: ['机床模型', '空压机模型', '机器人模型', 'PLC模型', '传感器模型'],
    }
  },
  created() {
    // 页面加载时从localStorage读取协议数据
    const saved = localStorage.getItem('protocols')
    if (saved) {
      this.protocols = JSON.parse(saved)
    } else {
      // 初始mock数据
      this.protocols = [
        {
          id: 1,
          name: '测试mqtt',
          type: 'MQTT',
          port: 1883,
          address: '192.168.1.10',
          timeout: 3000,
          autoReconnect: true,
          encryption: false,
          tls: false,
          enabled: true,
          favorite: false,
          createTime: '2025-04-04 05:39:46',
        },
        {
          id: 2,
          name: '测试TCP',
          type: 'TCP_SERVER',
          port: 9001,
          address: '192.168.1.20',
          timeout: 2000,
          autoReconnect: false,
          encryption: false,
          tls: false,
          enabled: false,
          favorite: false,
          createTime: '2025-04-05 05:49:25',
        },
        {
          id: 3,
          name: 'HTTP测试',
          type: 'HTTP_SERVER',
          port: 9001,
          address: '192.168.1.30',
          timeout: 5000,
          autoReconnect: false,
          encryption: false,
          tls: false,
          enabled: false,
          favorite: false,
          createTime: '2025-04-07 05:07:15',
        },
        {
          id: 4,
          name: '测试Websocket',
          type: 'WEBSOCKET_SERVER',
          port: 9002,
          address: '192.168.1.40',
          timeout: 4000,
          autoReconnect: true,
          encryption: false,
          tls: false,
          enabled: false,
          favorite: false,
          createTime: '2025-04-07 05:42:08',
        },
      ]
      this.saveProtocols()
    }
  },
  methods: {
    getProtocolIcon(type) {
      // 若图片加载失败，返回一个默认图片
      return protocolIcons[type] || require('@/assets/404_images/404.png')
    },
    onImgError(e) {
      e.target.src = require('@/assets/404_images/404.png')
    },
    openAddDialog() {
      this.dialogTitle = '新增协议'
      this.showDialog = true
      this.form = {
        id: null,
        type: '',
        name: '',
        address: '',
        port: 1883,
        timeout: 3000,
        autoReconnect: false,
        encryption: false,
        tls: false,
      }
    },
    openEditDialog(item) {
      this.dialogTitle = '编辑协议'
      this.showDialog = true
      this.form = { ...item }
    },
    submitForm() {
      this.$refs.formRef.validate(valid => {
        if (!valid) return
        if (this.form.id) {
          // 编辑
          const idx = this.protocols.findIndex(p => p.id === this.form.id)
          if (idx !== -1) this.$set(this.protocols, idx, { ...this.form })
        } else {
          // 新增
          const newId = this.protocols.length ? Math.max(...this.protocols.map(p => p.id)) + 1 : 1
          this.protocols.push({ ...this.form, id: newId, createTime: this.getNow() })
        }
        this.saveProtocols()
        this.showDialog = false
      })
    },
    resetDialog() {
      this.$refs.formRef && this.$refs.formRef.resetFields()
    },
    deleteProtocol(item) {
      this.$confirm('确定要删除该协议吗？', '提示', { type: 'warning' })
        .then(() => {
          this.protocols = this.protocols.filter(p => p.id !== item.id)
          this.saveProtocols()
        })
        .catch(() => {})
    },
    toggleEnable(item) {
      item.enabled = !item.enabled
      this.saveProtocols()
    },
    setFavorite(item) {
      item.favorite = !item.favorite
      this.saveProtocols()
    },
    // 设备适配测试
    openTestDialog(item) {
      this.showTestDialog = true
      this.testDeviceType = ''
      this.testResult = null
      this.currentTestProtocol = item
    },
    runTest() {
      // mock测试结果
      const rate = 90 + Math.floor(Math.random() * 10)
      this.testResult = {
        success: true,
        status: `已适配${rate}%主流工业设备`,
        rate,
        report: `${this.currentTestProtocol.type}协议与${this.testDeviceType}兼容性良好。`
      }
    },
    resetTestDialog() {
      this.testDeviceType = ''
      this.testResult = null
    },
    // 设备发现/手动添加
    openDiscoveryDialog(item) {
      this.showDiscoveryDialog = true
      this.discoveryTab = 'scan'
      this.scannedDevices = []
      this.currentDiscoveryProtocol = item
    },
    scanDevices() {
      // mock扫描结果
      this.scannedDevices = [
        { id: 'dev001', name: '机床A', status: '在线' },
        { id: 'dev002', name: '空压机B', status: '离线' },
        { id: 'dev003', name: '机器人C', status: '在线' },
      ]
    },
    associateDevice(device) {
      this.$message.success(`设备${device.name}已关联物模型！`)
    },
    addManualDevice() {
      if (!this.manualDevice.id || !this.manualDevice.name || !this.manualDevice.model) {
        this.$message.error('请填写完整信息')
        return
      }
      this.$message.success(`手动添加设备${this.manualDevice.name}成功！`)
      this.manualDevice = { id: '', name: '', param: '', model: '' }
    },
    resetDiscoveryDialog() {
      this.scannedDevices = []
      this.manualDevice = { id: '', name: '', param: '', model: '' }
    },
    getNow() {
      const d = new Date()
      return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')} ${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')}:${String(d.getSeconds()).padStart(2,'0')}`
    },
    saveProtocols() {
      localStorage.setItem('protocols', JSON.stringify(this.protocols))
    }
  }
}
</script>

<style scoped>
.protocol-management {
  padding: 24px;
}
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}
.protocol-list {
  margin-bottom: 20px;
  /* 左对齐 */
  justify-content: flex-start !important;
}
.protocol-col {
  margin-bottom: 20px;
  display: flex;
}
.protocol-card {
  min-height: 220px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 100%;
}
.card-header {
  display: flex;
  align-items: center;
}
.protocol-icon {
  width: 80px;
  height: 80px;
  margin-right: 16px;
  object-fit: contain;
  background: #f5f5f5;
  border-radius: 8px;
}
.protocol-info {
  flex: 1;
}
.protocol-title {
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 6px;
}
.card-footer {
  display: flex;
  align-items: center;
  margin-top: 10px;
  gap: 8px;
  border-top: 1px solid #ebeef5;
  padding-top: 10px;
  flex-wrap: wrap;
  /* 保证内容不超出卡片宽度 */
  overflow-x: auto;
}
.footer-name {
  max-width: 80px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-block;
}
</style>
